package org.dicr.util.jds;

import java.io.*;
import java.util.*;

import com.borland.dx.dataset.*;

/***********************************************************************************************************************
 * @author Igor A Tarasov me@dicr.dn.ua
 * @version 030128
 **********************************************************************************************************************/
public class DataMisc {

	/*******************************************************************************************************************
	 * Преобразование типа OBJECT в INPUTSTREAM
	 * 
	 * @param from object to transfer from
	 * @param to object to transfer to
	 * @throws IOException I/O exception
	 ******************************************************************************************************************/
	public static void objectToInputStream(Variant from, Variant to) throws IOException {
		if (!from.isNull()) {
			ByteArrayOutputStream baos = new ByteArrayOutputStream(50000);
			ObjectOutputStream oos = new ObjectOutputStream(baos);
			oos.writeObject(from.getObject());
			oos.flush();
			oos.close();
			baos.flush();
			byte[] b = baos.toByteArray();
			ByteArrayInputStream bin = new ByteArrayInputStream(b);
			bin.mark(b.length);
			to.setInputStream(bin);
		} else {
			to.setNull(Variant.ASSIGNED_NULL);
		}
	}

	/*******************************************************************************************************************
	 * Преобразование типа INPUTSTREAM в OBJECT
	 * 
	 * @param from object to transfer from
	 * @param to object to transfer to
	 * @throws IOException I/O exception
	 * @throws ClassNotFoundException class not found
	 ******************************************************************************************************************/
	public static void inputStreamToObject(Variant from, Variant to) throws IOException, ClassNotFoundException {
		Object obj = null;
		if (!from.isNull()) {
			InputStream in = from.getInputStream();
			if (in != null && in.available() > 0) {
				in.reset();
				ObjectInputStream ois = new ObjectInputStream(in);
				obj = ois.readObject();
			}
		}
		if (obj != null) to.setObject(obj);
		else to.setNull(Variant.ASSIGNED_NULL);
	}

	/*******************************************************************************************************************
	 * Возвращает список уникальных значений столбца dataset
	 * 
	 * @param dataset источник данных
	 * @param columnName колонка данных
	 * @return список уникальных значений в колонке
	 ******************************************************************************************************************/
	public static List<? extends Object> getUniqColumnValues(DataSet dataset, String columnName) {
		List<Object> values = new ArrayList<Object>();
		if (dataset != null && dataset.isOpen() && columnName != null && dataset.hasColumn(columnName) != null) {
			DataRow row = new DataRow(dataset, columnName);
			Variant v = new Variant();
			for (int i = 0; i < dataset.getRowCount(); i++) {
				dataset.getDataRow(i, row);
				row.getVariant(columnName, v);
				Object value = v.getAsObject();
				if (!values.contains(value)) values.add(value);
			}
		}
		return values;
	}

	/*******************************************************************************************************************
	 * Определяет признак модифицирования данных в DataSet
	 * 
	 * @param dataset dataset to check
	 * @return true if dataset is modofied
	 ******************************************************************************************************************/
	public static boolean isModified(DataSet dataset) {
		return dataset.getStorageDataSet().changesPending();
		/*
		 * try { if (dataset instanceof StorageDataSet) { StorageDataSet sdataset = (StorageDataSet)dataset; if
		 * (sdataset.getDeletedRowCount() > 0 || sdataset.getInsertedRowCount() > 0 || sdataset.getUpdatedRowCount() >
		 * 0) return true; } Column[] columns = dataset.getColumns(); if (columns != null) { for (int i = 0; i <
		 * columns.length; i++) try { if (dataset.isModified(columns[i].getOrdinal())) return true; } catch
		 * (NullPointerException ex) {} } } catch (Exception ex) { DicrExceptionHandler.handleException(ex, dataset); }
		 * return false;
		 */
	}

	/*******************************************************************************************************************
	 * Проверяет на определенность значений в MasterLink. Используется компонентами для запрещения редактирования
	 * DataSet в случае, если MasterLink DataSet в связующих колонках имеет неопределенные значения.
	 * 
	 * @param dataset dataset to check
	 * @return true if data is complete
	 * @throws DataSetException
	 ******************************************************************************************************************/
	public static boolean isMasterDataComplete(DataSet dataset) throws DataSetException {
		MasterLinkDescriptor masterDesc = dataset.getMasterLink();
		if (masterDesc == null) return true;
		DataSet masterData = masterDesc.getMasterDataSet();
		if (!masterData.isOpen() || masterData.isEditingNewRow()) return false;
		String masterCols[] = masterDesc.getMasterLinkColumns();
		for (int i = 0; i < masterCols.length; i++) {
			if (masterData.isNull(masterCols[i])) return false;
		}
		return true;
	}

	/*******************************************************************************************************************
	 * Проверяет редактируемость источника данных
	 * 
	 * @param dataset dataset to check
	 * @return true if dataset is editable
	 ******************************************************************************************************************/
	public static boolean isDataSetEditable(DataSet dataset) {
		if (dataset == null) return false;
		if (!dataset.isEditable()) return false;
		if (!dataset.isOpen()) return false;
		StorageDataSet stor = dataset.getStorageDataSet();
		if (stor != null && stor.isReadOnly()) return false;
		return isMasterDataComplete(dataset);
	}
}
